package ru.sgu.codecenter.fidx.command;

import ru.sgu.codecenter.fidx.OperationFailedException;
import ru.sgu.codecenter.fidx.model.HelpItem;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class RescanCommand extends Command {
    @Override
    public String getName() {
        return "rescan";
    }

    @Override
    public void execute(String[] args) {
        for (String arg : args) {
            rescanDirectory(new File(arg));
        }
    }

    private boolean isDirectoryScanned(String path) throws IOException {
        File directory = new File(path);
        path = directory.getCanonicalPath();
        if (path.charAt(path.length() - 1) != '\\' && path.charAt(path.length() - 1) != '/') {
            path += "\\";
        }

        if (!engine.findByFilePathPrefix(path).isEmpty()) {
            return true;
        }

        String[] files = directory.list();
        if (files == null || files.length == 0) {
            return true;
        }

        UpdateCommand updateCommand = new UpdateCommand();
        updateCommand.setEngine(engine);
        updateCommand.execute(new String[]{directory.getCanonicalPath()});
        return false;
    }

    private void rescanDirectory(File directory) {
        if (!directory.exists()) {
            throw new OperationFailedException("Cannot find directory \"" + directory + "\".");
        }

        if (!directory.isDirectory()) {
            throw new OperationFailedException("\"" + directory + "\" is not a directory.");
        }

        try {
            if (!isDirectoryScanned(directory.getCanonicalPath())) {
                return;
            }

            int addedDirectoryCount = 0;
            final String[] innerFileNames = directory.list();
            if (innerFileNames != null) {
                for (String innerFileName : innerFileNames) {
                    File innerFile = new File(directory, innerFileName);
                    if (innerFile.exists() && innerFile.isDirectory()) {
                        if (!isDirectoryScanned(innerFile.getCanonicalPath())) {
                            addedDirectoryCount++;
                        }
                    }
                }
            }

            info(addedDirectoryCount + " directories have been added to the index.");
        } catch (IOException e) {
            throw new OperationFailedException("Unable to rescan directory \"" + directory + "\"", e);
        }
    }

    @Override
    public List<HelpItem> getHelpItems() {
        List<HelpItem> helpItems = new ArrayList<HelpItem>();
        helpItems.add(new HelpItem(getName() + " <directory>", "find <directory> and subdirectories (not recursively) in the index, automatically add"));
        return helpItems;
    }
}
